#ifndef SOCKETTHREAD_H
#define SOCKETTHREAD_H

#include <QObject>
#include <QTcpSocket>
#include "multithread.h"
#include <string.h>

class SocketThread : public MultiThread
{
    Q_OBJECT
public:
    explicit SocketThread(QString _objName, QObject *parent = nullptr);
    void IP(const QString _hostName, quint16 _port)
    {
        hostName = _hostName;
        port = _port;
        _busy = 0;
        socket_err = 0;
    }
    /*void CloseSocket(void)
    {
        if(nullptr!=socket)
        {
            //socket->close();
        }
    }*/
    int busy(void)
    {
        return  _busy;
    }
    void send(const int sockfd, const void *buf, const uint16_t len)
    {
        (void)sockfd;
        socket->write((const char*)buf, (qint64)len);
        socket->flush();
        socket->waitForBytesWritten();
    }
    qint64 crecv(const int sockfd, void *buf, const uint16_t _rsize, int msecs = 30000)
    {
        qint64 _size=0;
        (void)sockfd;
        socket->waitForReadyRead(msecs);
        _size = socket->read((char *)buf, (qint64)_rsize);
        return _size;
    }

signals:

public slots:
    virtual void doWork(const QString parameter) override;

protected slots:
    void connected()
    {
        qDebug() << objName << " -- readyRead " << socket->readAll();
    }
    void readyRead()
    {
        qDebug() << objName << " -- connected  successfully";
    }
    void error(QAbstractSocket::SocketError socketError)
    {
        qDebug() << objName << " -- error " << socketError;
        socket_err = 1;
    }

protected:
    virtual int init(const QString _hostName, const quint16 _port)
    {
        //const char data[] = "Connect";
        // 1. 创建TCP套接字对象
        if(nullptr==socket)
            socket = new QTcpSocket(this);
        socket->abort();        //取消原有连接
        // 2. 已连接、数据可读、失败信号连接
        //connect(socket, &QTcpSocket::connected, this, &SocketClient::connected);
        connect(socket, &QIODevice::readyRead, this, &SocketThread::readyRead);
        typedef void (QAbstractSocket::*QAbstractSocketErrorSignal)(QAbstractSocket::SocketError);
        connect(socket, static_cast<QAbstractSocketErrorSignal>(&QTcpSocket::error), this, &SocketThread::error);
        //3. 与服务器端建立连接
        //socket->connectToHost("39.108.72.130", 9910, QTcpSocket::ReadWrite);
        socket->connectToHost(_hostName, _port, QTcpSocket::ReadWrite);
        socket->waitForConnected();
        //4. 同步处理-等待数据可读
        //socket->waitForReadyRead();
//        socket->write(data, strlen(data));
//        socket->flush();
//        socket->waitForBytesWritten();
        return  0;
    }

protected:
    QString hostName;
    quint16 port;
    const QString objName;
    QTcpSocket *socket;
    int socket_err;
    int _busy;

};

// 线程池，并发测试
class Thread_Pond : public SocketThread
{
    Q_OBJECT
public:
    explicit Thread_Pond(QObject *parent = nullptr) : SocketThread("Thread_Pond", parent)
    {
        memset(thread_pond, 0, sizeof(thread_pond));
        memset(_controller_pond, 0, sizeof(_controller_pond));
    }

public slots:
    virtual void doWork(const QString parameter) override;
    void handleThread(const QString result, const void* data)
    {
        emit resultReady(result, data);
    }

private:
    SocketThread *thread_pond[1024]; // 线程池
    ControllerMultiThread *_controller_pond[1024];

};

class SocketThreadViewer : public SocketThread
{
    Q_OBJECT
public:
    explicit SocketThreadViewer(QObject *parent = nullptr) : SocketThread("SocketThreadViewer", parent)
    {
//        memset(vin_list, 0, sizeof (vin_list));
//        vin_now = 0;
        socket = nullptr;
    }

//    void vin_list_add(const char vin[]);
//    char* vin_list_for_each(uint16_t *_index);

signals:

public slots:
    virtual void doWork(const QString parameter) override;

private slots:
    void connected();
    void readyRead();
    void error(QAbstractSocket::SocketError socketError);
private:
    void _init(const QString _hostName, const quint16 _port);
protected:
    virtual int init(const QString _hostName, const quint16 _port) override
    {
#if 1
        int i=0;
        const char viewer[] = "SocketViewer";
        SocketThread::init(_hostName, _port);
        //socket->waitForReadyRead();
//        socket->write(viewer, strlen(viewer));
//        socket->flush();
//        socket->waitForBytesWritten();
        for(i=0; i<20; i++)
        {
            socket->write(viewer, strlen(viewer));
            socket->flush();
            socket->waitForBytesWritten();
            QThread::msleep(100);
        }
#else
        _init(_hostName, _port);
#endif
        return 0;
    }

private:
    //QTcpSocket *socket;
    static int load; // 重载标志

//    char vin_list[1024][32];
//    uint16_t vin_now;

};

#endif // SOCKETTHREAD_H
